package com.ubing.gxspringboot.gxservlet;

import com.ubing.gxspringboot.gxapplicationcontext.GXWebApplicationContext;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Map;

public class GXDispatcherServlet extends HttpServlet {
    GXWebApplicationContext webApplicationContext;
    public GXDispatcherServlet(GXWebApplicationContext webApplicationContext){
        this.webApplicationContext=webApplicationContext;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        dispatcherServlet(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        dispatcherServlet(req,resp);
    }

    private void dispatcherServlet(HttpServletRequest req, HttpServletResponse resp){
        Map<String, String[]> parameterMap = req.getParameterMap();
        Method method = (Method)webApplicationContext.getPathIoc().get(req.getRequestURI());
        try {
        Parameter[] parameters = method.getParameters();
        Object instance = webApplicationContext.getWebIoc().get(method);
        try {
            Object[] methodParameters = new Object[parameters.length];
            int i=0;
            for (Parameter parameter : parameters) {
                Constructor<String> constructor = String.class.getConstructor(String.class);
                String name = parameter.getName();
                String s = constructor.newInstance( Arrays.asList(parameterMap.get(name)).get(0));
                methodParameters[i]=s;
                i++;
            }
            Object invoke = method.invoke(instance,methodParameters);
            ServletOutputStream outputStream = resp.getOutputStream();
            outputStream.write(invoke.toString().getBytes());
        } catch (IllegalAccessException | InvocationTargetException | IOException | InstantiationException |
                 NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (NullPointerException e) {
            try {
                ServletOutputStream outputStream = resp.getOutputStream();
                outputStream.write("code: 400 can find serve".getBytes());
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
        }catch (NullPointerException e){
//            System.out.println("方法参数为null");
        }
    }
}
